package com.fucking.great.servlert;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.fucking.great.context.GreatMain;
import com.fucking.great.context.TxnContext;
import com.fucking.great.context.common.DynGraphqlResolver;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

@WebServlet(HadnlerServlet.TXN_PATH+"*")
public class HadnlerServlet extends HttpServlet {
    public static final String TXN_PATH = "/txn/";
    public static final Log log = LogFactory.get();
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 为了使用ServletUtil
        ServletUtil.set(request, response);

        try {
            //
            TxnContext context = initContextByRequest(request);

            // 改为实体.
            handlerContext(response, context);

        } catch (Throwable e) {
            log.trace(e);
        }finally {
            ServletUtil.removue();
        }
    }

    public static void handlerContext(HttpServletResponse response, TxnContext context) throws IOException {
        // 改为实体.
        Object invoke =  GreatMain.doService(context);
//            System.out.println("println-view="+invoke);

        //
        if(context.hasException()){
            String errorCode = context.getErrorCode();
            int status;
            try {
                status = Integer.parseInt(errorCode);
            } catch (NumberFormatException e) {
                status = 500;
            }
            response.setStatus(status);
        }
        // 默认响应头
        response.setContentType("application/json");
        //
        response.setCharacterEncoding("utf-8");
        //
        context.getResponseHeader().forEach( (key,value) -> {
            response.setHeader(key,StrUtil.utf8Str(value));
        });
        PrintWriter printWriter = response.getWriter();

        printWriter.println(invoke);
        printWriter.flush();
        printWriter.close();
    }
    public static DynGraphqlResolver initDynGraphqlByRequest(HttpServletRequest servletRequest) {
        TxnContext context = initByRequest(servletRequest);
        Map<String, String> paramMap = ServletUtil.getParamMap(servletRequest);
        context.getHeader().putAll(paramMap);
        // init，config。
        //HadnlerInterface.ONE.initConfig(context.getPath());

        // 准备context转化参数
        String body = ServletUtil.getBody(servletRequest);
        DynGraphqlResolver dynGraphqlResolver = new DynGraphqlResolver(body);
//        JSONObject resultJson = dynGraphqlResolver.run();

//        HadnlerInterface.ONE.endService();

        return dynGraphqlResolver;
    }
    public static TxnContext initContextByRequest(HttpServletRequest servletRequest) {
        TxnContext context = initByRequest(servletRequest);
        // 准备context转化参数
        String body = ServletUtil.getBody(servletRequest);
        JSONObject jsonParaM ;
        if(JSONUtil.isJsonObj(body)){
            jsonParaM = JSONUtil.parseObj(body);
        }else{
            jsonParaM = new JSONObject();
        }

        // 和json合并
        Map<String, String> paramMap = ServletUtil.getParamMap(servletRequest);
        jsonParaM.putAll(paramMap);
        //放入PARAM
        context.putAll(jsonParaM);
        return context;
    }

    /**
     * 初始init公共参数.
     * @param servletRequest
     * @return
     */
    private static  TxnContext initByRequest(HttpServletRequest servletRequest) {
        TxnContext context = TxnContext.getContext();
        // 放置 头信息
        Map<String, String> headerMap = ServletUtil.getHeaderMap(servletRequest);
        context.putHeader(headerMap);
        // 从头信息里面获得多余的内容
        JSONObject header = context.getHeader();
        // bug : 消息头只有小写。
        Integer logLevel = header.getInt("log-level",100);
        context.setLogLevel(logLevel);
        //
        String systemName = header.getStr("system", "");
        context.setSystemName(systemName);
        //
        String clientIPByHeader = ServletUtil.getClientIPByHeader(servletRequest);
        context.setClientIp(clientIPByHeader);
        //
        StringBuffer requestURL = servletRequest.getRequestURL();
        context.setUrl(requestURL.toString());
        // 放servletPath标识.
        String servletPath = ServletUtil.getServletPath(servletRequest);
        servletPath = StrUtil.subAfter(servletPath, HadnlerServlet.TXN_PATH, false);
        context.setPath(servletPath);
        //
        context.setLocale(servletRequest.getLocale());
        context.setType("http");
        return context;
    }



    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
